package com.woniushop.dao;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.woniushop.utils.JdbcUtils;

/**
 * 用于执行基本的DAO操作，如增删改查
 * 
 * @author 崔新雄
 *
 * @param <T>
 */
public class BaseDAO<T> {
	Connection conn;
	PreparedStatement stat;
	ResultSet rs;

	/**
	 * 执行增、删、改操作
	 * 
	 * @param sql
	 * @param objs
	 */
	public void update(String sql, Object... objs) {
		try {
			conn = JdbcUtils.getConn();
			stat = conn.prepareStatement(sql);
			for (int i = 0; i < objs.length; i++) {
				stat.setObject((i + 1), objs[i]);
			}
			stat.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.closeConn(rs, stat, conn);
		}
	}

	/**
	 * 执行查询数据语句
	 * 
	 * @param sql
	 * @param c
	 * @param objs
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> select(String sql, Class<T> c, Object... objs) {
		List<T> list = new ArrayList<T>();
		try {
			conn = JdbcUtils.getConn();
			stat = conn.prepareStatement(sql);
			for (int i = 0; i < objs.length; i++) {
				stat.setObject((i + 1), objs[i]);
			}
			rs = stat.executeQuery();
			Method[] methods = c.getMethods();
			while (rs.next()) {
				Object obj = c.newInstance();
				for (Method method : methods) {
					String methodName = method.getName();
					if (methodName.startsWith("set")) {
						Class<?>[] parameterTypers = method.getParameterTypes();
						String fileName = methodName.substring(3).toLowerCase();
						if (parameterTypers[0] == Integer.class) {
							method.invoke(obj, rs.getInt(fileName));
						} else if (parameterTypers[0] == String.class) {
							method.invoke(obj, rs.getString(fileName));
						} else if (parameterTypers[0] == BigDecimal.class) {
							method.invoke(obj, rs.getBigDecimal(fileName));
						} else if (parameterTypers[0] == Date.class) {
							method.invoke(obj, rs.getDate(fileName));
						} else {
							method.invoke(obj, rs.getObject(fileName));
						}
					}
				}
				list.add((T) obj);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} finally {
			JdbcUtils.closeConn(rs, stat, conn);
		}
		return list;
	}
	
	public Integer count(String sql, Object... objs) {
		try {
			conn = JdbcUtils.getConn();
			stat = conn.prepareStatement(sql);
			for (int i = 0; i < objs.length; i++) {
				stat.setObject((i + 1), objs[i]);
			}
			rs = stat.executeQuery();
			if (rs.next()) {
				return rs.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
}
